﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Zeta.Game;

namespace LocationTracker
{

    public static class Dumper
    {

        /// <summary>
        /// Saves the location cache to files
        /// </summary>
		
		
        public static void Save()
        {

            var ExportConfig = new List<ActorLocationType>(){
                ActorLocationType.Elite,
                ActorLocationType.Unique,
                ActorLocationType.Rare,
                ActorLocationType.Goblin,
                ActorLocationType.Objective,
                ActorLocationType.Event,
                ActorLocationType.Portal
            };

            try
            {
                if (ZetaDia.CurrentWorldId <= 0 || ZetaDia.Me.ActorClass == Zeta.Game.ActorClass.Invalid)
                {
                    return;
                }
				
				//kyriakos hack to output current status, will assist in bounty debugging
                string CurrentWorldDynamicId = ZetaDia.CurrentWorldDynamicId.ToString();
                string CurrentWorldId = ZetaDia.CurrentWorldId.ToString();
                //string CurrentLevelId = ZetaDia.CurrentLevelId.ToString();
                string LevelId = ZetaDia.WorldInfo.Name.ToString();					
				var kyriakosfilename = Path.Combine(FileManager.LoggingPath, String.Format("bountytimer.csv"));                
                try 
                {
                    string activeBountyId = ZetaDia.ActInfo.ActiveBounty.Info.QuestSNO.ToString();
                    string QuestState = ZetaDia.ActInfo.ActiveBounty.State.ToString();
                    string Quest = ZetaDia.ActInfo.ActiveBounty.Quest.ToString();
                    string QuestType = ZetaDia.ActInfo.ActiveBounty.Info.QuestType.ToString();
                    using (var KyriakosLogWriter = new StreamWriter(kyriakosfilename, true))
                    {
                        KyriakosLogWriter.Write(ZetaDia.Me.Position.X + "," + ZetaDia.Me.Position.Y + "," + activeBountyId + "," + QuestState + "," + Quest + "," + CurrentWorldId + "," + LevelId + "," + CurrentWorldDynamicId + "," + QuestType + "," + DateTime.Now + "\r\n");
                    }
                } catch { 
                    using (var KyriakosLogWriter = new StreamWriter(kyriakosfilename, true))
                    {
                        KyriakosLogWriter.Write(ZetaDia.Me.Position.X + "," + ZetaDia.Me.Position.Y + "," + "," + "," + "," + CurrentWorldId + "," + LevelId + "," + "," + "," + DateTime.Now + "\r\n");
                    }
                }
				//endkyriakos

                var cache = Cache.cache;
                var writeHeader = false;

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                if (cache != null && cache.Count > 0)
                {

                    Logger.Log("Logging New Monster Locations:");

                    foreach (int levelId in cache.Keys)
                    {

                        var filename = Path.Combine(FileManager.LoggingPath, String.Format("locations.{0}.js", levelId));

                        if (File.Exists(filename))
                        {
                            FileManager.DeleteLastLine(filename);
                        }
                        else
                        {
                            writeHeader = true;
                        }

                        using (var LogWriter = new StreamWriter(filename, true))
                        {

                            //LogWriter.Write(Cache.cache.Count() +" worlds, " + cache[worldId].Count + "cached mobs for world:" + worldId + ",  \n");

                            if (writeHeader)
                            {
                                LogWriter.Write("var data" + levelId + " = [\n");
                            }

                            foreach (var mob in cache[levelId])
                            {
                                //LogWriter.Write(mob.Name + " " + mob.Type + " " + mob.TypeName + " \n");
                                var friendlyMobName = (new Regex(@"-\d+$", RegexOptions.Compiled)).Replace(mob.Name, "");
                                var questString = (mob.IsBountyObjective) ? "QuestId = "+mob.BountyObjectiveQuestId : string.Empty;

                                foreach (var item in ExportConfig.Select((value, index) => new { index, value }))
                                {
                                    if (item.value == mob.Type)
                                    {
                                        if(mob.IsBountyObjective){
                                            LogWriter.WriteLine("// OBJECTIVE " + questString + " ActorID=" + mob.ActorSNO + " ActorName=" + mob.Name + " Quest name=" + ZetaDia.ActInfo.ActiveBounty.Quest.ToString());
                                        }

                                        LogWriter.WriteLine(FormatGoogleScatterField(mob.X, mob.Y, mob.Name + " (" + mob.ActorSNO + ")", item.index + 1, ExportConfig.Count));

                                        Logger.Log("{0} --> {1} {2}: [{3},{4}] {5} ({6})", levelId, questString, mob.Type, mob.X, mob.Y, friendlyMobName, mob.ActorSNO);

                                    }
                                }

                            }

                            LogWriter.Write("]");

                        }
                    }

                }
                else
                {
                    //Logger.Log("Cache is empty");
                }

                stopwatch.Stop();

                //Logger.Log("Time to Save Files: {0}ms", stopwatch.Elapsed.Milliseconds);

            }
            catch (Exception ex)
            {
                Logger.Log(ex.ToString());
            }


        }

        private static string FormatGoogleScatterField(int x, int y, int seriesIndex, int totalFields)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("[{0}", y);
            for (int i = 1; i <= totalFields; i++)
            {
                if (i == seriesIndex)
                {
                    sb.AppendFormat(",{0}", x);
                }
                else
                {
                    sb.Append(",null");
                }
            }
            sb.Append("],\n");
            return sb.ToString();
        }

        private static string FormatGoogleScatterField(int x, int y, string tooltip, int seriesIndex, int totalFields)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("[{0}", y);
            for (int i = 1; i <= totalFields; i++)
            {
                if (i == seriesIndex)
                {
                    sb.AppendFormat(",{0},'{1}'", x, tooltip);
                }
                else
                {
                    sb.Append(",null,''");
                }
            }
            sb.Append("],\n");
            return sb.ToString();
        }


        /// <summary>
        /// Gets the Logging path
        /// </summary>

    }

}
